package com.zhoug.tmap;

import androidx.annotation.NonNull;

import com.zhoug.logging.Logger;

import org.osmdroid.events.DelayedMapListener;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
import org.osmdroid.util.BoundingBox;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;

import java.util.List;

/**
 * 行政区域边界绘制管理器
 *
 * @Author: zhoug
 * @Date: 2025-01-06
 * @Description:
 */
public class PolygonMaskManager {
    private static final String TAG = ">>>PolygonMaskManager";
    private static final boolean DEBUG = false;

    private PolygonMask mPolygonMask;
    private MapView mMapView;
    /**
     * 限制滚动范围
     */
    private boolean mIsLimitBounds = true;
    /**
     * 边距
     */
    private int boundPadding = 30;
    /**
     * 限制最小缩放级别
     */
    private boolean mIsLimitMinZoom = true;
    private boolean mShouldLimitZoom = false;
    private final MapBoundsComputor mMapBoundsComputor = new MapBoundsComputor();
    /**
     * 是否动画执行
     */
    private boolean mIsAnimated = true;
    /**
     * 动画速度
     */
    private Long mAnimationSpeed;

    public PolygonMaskManager(MapView mapView) {
        this.mMapView = mapView;
    }

    /**
     * 设置边界
     *
     * @param polygon
     */
    public void set(@NonNull PolygonMask polygon) {
        if (mPolygonMask != null) {
            mMapView.getOverlays().remove(mPolygonMask);
        }
        mPolygonMask = polygon;
        //遮罩添加到最底层
        mMapView.getOverlays().add(0, polygon);
        limitBounds();
        mMapView.postInvalidate();
    }

    /**
     * 清除边界
     */
    public void clear() {
        if (mPolygonMask != null) {
            mPolygonMask.remove();
        }
    }

    /**
     * 缩放地图
     */
    private void limitBounds() {
        mMapBoundsComputor.reset();
        //计算边界
        List<PolygonMask.PolygonHole> polygonBounds = mPolygonMask.getPolygonBounds();
        if (polygonBounds != null && !polygonBounds.isEmpty()) {
            for (PolygonMask.PolygonHole polygonHole : polygonBounds) {
                List<GeoPoint> actualPoints = polygonHole.getActualPoints();
                if (actualPoints != null && !actualPoints.isEmpty()) {
                    for (GeoPoint geoPoint : actualPoints) {
                        mMapBoundsComputor.addLatLng(geoPoint.getLatitude(), geoPoint.getLongitude());
                    }
                }
            }
        }
        MapBound bound = mMapBoundsComputor.getBound();
        if (bound != null) {
            //限制最新缩放
            if (mIsLimitMinZoom) {
                mMapView.setMinZoomLevel(3.0);
                mShouldLimitZoom = true;
                mMapView.addMapListener(mLimitZoomListener);
            }
            //限制移动边界
            if (mIsLimitBounds && !bound.isOnlyOnePoint()) {
                mMapView.setScrollableAreaLimitLatitude(bound.getMaxLatitude(), bound.getMinLatitude(), boundPadding);
                mMapView.setScrollableAreaLimitLongitude(bound.getMinLongitude(), bound.getMaxLongitude(), boundPadding);
            }
            //全部点显示在地图上
            if (!bound.isOnlyOnePoint()) {
                //不开启动画,不能准确的移动到中心
                BoundingBox boundingBox = new BoundingBox(bound.getMaxLatitude(), bound.getMaxLongitude(),
                        bound.getMinLatitude(), bound.getMinLongitude());
                Long speed=mIsAnimated ? mAnimationSpeed : Long.valueOf(10);
                mMapView.zoomToBoundingBox(boundingBox, true, boundPadding, mMapView.getMaxZoomLevel(),speed );
            } else {
                //只有一个点
                GeoPoint geoPoint = new GeoPoint(bound.getMaxLatitude(), bound.getMaxLongitude());
                if (mIsAnimated) {
                    mMapView.getController().animateTo(geoPoint);
                } else {
                    mMapView.getController().setCenter(geoPoint);
                }
            }
            mMapView.postInvalidate();
        }


    }

    /**
     * 限制滚动范围
     *
     * @param limitBounds
     */
    public void setLimitBounds(boolean limitBounds) {
        this.mIsLimitBounds = limitBounds;
    }

    /**
     * 限制最新缩放级别
     *
     * @param isLimitMinZoom
     */
    public void setLimitMinZoom(boolean isLimitMinZoom) {
        this.mIsLimitMinZoom = isLimitMinZoom;
    }

    /**
     * 设置边距
     *
     * @param boundPadding
     */
    public void setBoundPadding(int boundPadding) {
        this.boundPadding = boundPadding;
    }

    /**
     * 是否动画执行
     *
     * @param isAnimated
     */
    public void setIsAnimated(boolean isAnimated) {
        this.mIsAnimated = isAnimated;
    }

    /**
     * 动画速度
     *
     * @param animationSpeed
     */
    public void setAnimationSpeed(Long animationSpeed) {
        this.mAnimationSpeed = animationSpeed;
    }

    private final DelayedMapListener mLimitZoomListener = new DelayedMapListener(new MapListener() {
        @Override
        public boolean onScroll(ScrollEvent event) {
            onChange();
            return false;
        }

        @Override
        public boolean onZoom(ZoomEvent event) {
            onChange();
            return false;
        }

        private void onChange() {
            double zoomLevelDouble = mMapView.getZoomLevelDouble();
            if (DEBUG) {
                Logger.d(TAG, "onChange:" + zoomLevelDouble);
            }
            if (mShouldLimitZoom) {
                mShouldLimitZoom = false;
                mMapView.setMinZoomLevel(zoomLevelDouble);
            }
            mMapView.removeMapListener(mLimitZoomListener);
        }
    }, 100);


}
